#ifndef RENDERER_CONFIG
#define RENDERER_CONFIG

/// Utils Lib
#include "Utils/All.hpp"

/// SFML
#include "SFML/Graphics.hpp"

/// Open GL 3
#ifdef REDWIN32
#	define GLEW_STATIC 1
#	include "GL/glew.h"
#else
#	define GL3_PROTOTYPES 1
#	include <GL3/gl3.h>
#endif

/// Anisotropic extension definition
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF

/// DLL managment under WIN32
	#ifdef REDWIN32
	#	ifdef REDEXPORTS
	#		define REDAPI __declspec(dllexport)
	#	else
	#		define REDAPI __declspec(dllimport)
	#	endif
	#	ifdef _MSC_VER
    #		pragma warning(disable : 4251)
    #		pragma warning(disable : 4661)
	#	endif
	#else
	#	define REDAPI
	#endif

namespace red{

/// Function Definition for RedEngine - SFML - OpenGL liaison
	
	/// \brief Function used to get a glError in string format
	inline std::string GetGLErrorStr(GLenum glError){
		switch(glError){
		case GL_NO_ERROR : return "GL_NO_ERROR";
		case GL_INVALID_ENUM : return "GL_INVALID_ENUM";
		case GL_INVALID_VALUE : return "GL_INVALID_VALUE";
		case GL_INVALID_OPERATION : return "GL_INVALID_OPERATION";
		case GL_STACK_OVERFLOW : return "GL_STACK_OVERFLOW";
		case GL_STACK_UNDERFLOW : return "GL_STACK_UNDERFLOW";
		case GL_OUT_OF_MEMORY : return "GL_OUT_OF_MEMORY";
		case GL_TABLE_TOO_LARGE : return "GL_TABLE_TOO_LARGE";
		default : return "Unknown Error";
		}
	}

	/// \brief SFML to RedEngine Color conversion
	inline red::Color ToRedColor(const sf::Color &pColor){
		return red::Color(pColor.r / 255.f, pColor.g / 255.f, pColor.b / 255.f, pColor.a / 255.f);
	}
	
	/// \brief RedEngine to SFML Color conversion
	inline sf::Color ToSFMLColor(const red::Color &pColor){
		return sf::Color(static_cast<u8>(pColor.R() * 255), 
						 static_cast<u8>(pColor.G() * 255), 
						 static_cast<u8>(pColor.B() * 255), 
						 static_cast<u8>(pColor.A() * 255));
	}

	/// \brief SFML to RedEngine Vector2f conversion
	template<class T> inline red::Vector2F ToRedVector2F(const sf::Vector2<T> &pVec){
		return red::Vector2F(static_cast<f32>(pVec.x), static_cast<f32>(pVec.y));
	}
	
	/// \brief SFML to RedEngine Vector2i conversion
	template<class T> inline red::Vector2I ToRedVector2I(const sf::Vector2<T> &pVec){
		return red::Vector2I(static_cast<s32>(pVec.x), static_cast<s32>(pVec.y));
	}
	
	/// \brief RedEngine to SFML Vector2f conversion
	template<class T> inline sf::Vector2f ToSFMLVector2f(const red::Vector2<T> &pVec){
		return sf::Vector2f(static_cast<f32>(pVec.x), static_cast<f32>(pVec.y));
	}
	
	/// \brief RedEngine to SFML Vector2i conversion
	template<class T> inline sf::Vector2i ToSFMLVector2i(const red::Vector2<T> &pVec){
		return sf::Vector2i(static_cast<s32>(pVec.x), static_cast<s32>(pVec.y));
	}
}
#endif